<template>
  <div class="upload-file">
    <a-upload
      v-bind="attrs"
      v-model:fileList="fileList"
      :action="action"
      name="file"
      :maxCount="maxCount"
      :multiple="multiple"
      :headers="headers"
      :customRequest="uploadRequest"
      :before-upload="beforeUpload"
      @change="handleChange"
      @preview="handlePreview"
      @remove="removeFileHandle"
    >
      <slot>
        <a-button>
          <upload-outlined></upload-outlined>
          {{ btnText }}
        </a-button>
      </slot>
    </a-upload>
    <!-- 是否支持粘贴 -->
    <div v-if="canPast" class="past-wrapper">
      <div class="past-contener" contenteditable :id="pastId"></div>
      <div class="past-tip">
        <div><i class="el-icon-document-copy"></i></div>
        粘贴图片上传
      </div>
    </div>
    <a-modal :visible="previewVisible" :title="previewTitle" :footer="null" @cancel="handleCancel">
      <img alt="图片预览" style="width: 100%" :src="previewImage" />
    </a-modal>
  </div>
</template>
<script lang="ts">
export default {
  name: "UploadFile"
};
</script>
<script lang="ts" setup>
import { message } from "ant-design-vue";
import { UploadOutlined } from "@ant-design/icons-vue";
import type { UploadFile, UploadProps } from "ant-design-vue";
import type { UploadChangeParam } from "ant-design-vue";
import { computed, onMounted, ref, toRefs, useAttrs, watch } from "vue";
import { getAuthent } from "@/utils/auth";
import InitHook from "./composables/initHook";
const props = withDefaults(
  defineProps<{
    canPast?: boolean;
    btnText?: string;
    multiple?: boolean;
    mode: string;
    valueType?: string;
    value: Array<Base.GeneraDataType>;
    uploadRequest?: (e: any) => void;
    maxCount?: number;
    overShow?: boolean; // 是否需要回显 （详情使用）
  }>(),
  {
    btnText: () => "上传",
    valueType: "1", // '1' 返回纯链接    '2' 返回文件对象
    multiple: true,
    uploadRequest: undefined,
    canPast: false,
    maxCount: 999,
    overShow: true // 是否需要回显 （详情使用）
  }
);
const emit = defineEmits<{
  (e: "update:value", fileList: Array<Base.GeneraDataType>): void;
}>();
const attrs = useAttrs();

const { btnText, uploadRequest, multiple, mode, value, valueType, canPast, maxCount, overShow } = toRefs(props);
const pastId = ref<string>(Date.now().toString());
const fileList = ref<Array<Base.GeneraDataType>>([]);
const previewVisible = ref<boolean>(false);
const previewImage = ref<string>("");
const previewTitle = ref<string>("");
const action = computed<string>(() => {
  return `${process.env.VUE_APP_BASE_API}/base/sys/upload?path=${mode.value}`;
});
const headers = {
  Authorization: getAuthent("token")
};
const { initPastImg } = InitHook({ pastId, maxCount, fileList });
const handleChange = (info: UploadChangeParam) => {
  if (info.file.status === "done") {
    const hasUploading = info.fileList.findIndex((t: UploadFile) => t.status !== "done");
    if (hasUploading === -1) {
      message.success(`${info.file.name} 文件上传成功!`);
      if (valueType.value === "1") {
        emit(
          "update:value",
          info.fileList.map((t: any) => {
            if (t.response) {
              return t.response.data.url;
            } else {
              return t.url;
            }
          })
        );
      } else {
        const addItems = info.fileList.filter((t: any) => t.response);
        emit(
          "update:value",
          value.value.concat(
            addItems.map((t: any) => {
              return {
                ...t.response.data,
                attr: null,
                hashInfo: null,
                metadata: null,
                thMetadata: null,
                thUserMetadata: null,
                userMetadata: null
              };
            })
          )
        );
      }
    }
  } else if (info.file.status === "error") {
    message.error(`${info.file.name} 文件上传失败!`);
  }
};
const beforeUpload: UploadProps["beforeUpload"] = file => {
  return new Promise((resolve, reject) => {
    if (file.size / 1024 / 1024 > 50) {
      message.error("文件大小不能超过50M!");
      reject("文件大小不能超过500M!");
    }
    resolve();
  });
};
const handlePreview = async (file: any) => {
  previewImage.value = file.thumbUrl || file.response.data.url;
  previewVisible.value = true;
  previewTitle.value = file.name || file.response.data.url.substring(file.response.data.url.lastIndexOf("/") + 1);
};
const handleCancel = () => {
  previewVisible.value = false;
  previewTitle.value = "";
};
const removeFileHandle = (e: any) => {
  if (valueType.value === "1") {
    const result = value.value.filter((t: any) => t !== e.url);
    emit("update:value", result);
  } else {
    const result = value.value.filter((t: any) => t.url !== e.url);
    emit(
      "update:value",
      result.map((t: any) => {
        if (t.thumbUrl) return t;
        else
          return {
            uid: `${t.url}`,
            name: t.originalFilename,
            status: "done",
            url: t.url,
            thumbUrl: t.url
          };
      })
    );
  }
};
watch(
  () => value.value,
  () => {
    //如果关闭弹窗 数组清空
    if (!value.value.length || !value.value) {
      return (fileList.value = []);
    }

    if (overShow.value) {
      if (valueType.value === "1") {
        fileList.value = value.value.map((url: any) => {
          return {
            uid: `${url}`,
            name: url.originalFilename || url.name || `${url.split("/")[url.split("/").length - 1]}`,
            status: "done",
            url,
            thumbUrl: url
          };
        });
      } else {
        fileList.value = value.value.map((t: any) => {
          return {
            uid: `${t.url}`,
            name: t.originalFilename || t.name || `${t.split("/")[t.split("/").length - 1]}`,
            status: "done",
            url: t.url,
            thumbUrl: t.url
          };
        });
      }
    }
  }
);
onMounted(() => {
  //如果关闭弹窗 数组清空
  if (!value.value.length || !value.value) {
    return (fileList.value = []);
  }

  if (overShow.value) {
    if (valueType.value === "1") {
      fileList.value = value.value.map((url: any) => {
        return {
          uid: `${url}`,
          name: url.originalFilename || url.name || `${url.split("/")[url.split("/").length - 1]}`,
          status: "done",
          url,
          thumbUrl: url
        };
      });
    } else {
      fileList.value = value.value.map((t: any) => {
        return {
          uid: `${t.url}`,
          name: t.originalFilename || t.name || `${t.split("/")[t.split("/").length - 1]}`,
          status: "done",
          url: t.url,
          thumbUrl: t.url
        };
      });
    }
  }
  if (canPast.value) {
    initPastImg();
  }
});
</script>
<style lang="stylus" scoped>
.past-wrapper {
    position: relative;
    width: 150px;
    cursor: pointer;
    .past-contener {
        border: 1px dashed #ccc;
        cursor: pointer;
        border-radius: 5px;
        height: 150px;
        width: 150px;
        display: flex;
        align-items: center;
        justify-content: center;
    }
    .past-tip {
        position: absolute;
        color: #ccc;
        font-weight: 600;
        text-align: center;
        top: 50%;
        transform: translate3d(-50%, -50%, 0);
        left: 50%;
        width: 100%;
    }
}
</style>
